<template>
  <div class='FcInputTable'>
    <div class="fc-table-box" :class="config.type">
      <!-- 表格模式 -->
      <el-table
          size="small"
          v-if="showTable"
          :data="tableFormData"
          border
          class="fc-table"
          v-bind="config.tableConf || {}"
          :show-summary="config['show-summary']"
          :summary-method="getTableSummaries"
      >
        <el-table-column width="50" align="center">
          <template #default="scope">
            <div class="row-action">
              <span class="index">{{ scope.$index + 1 }}</span>
              <ElPopconfirm
                  title="确定删除该行数据吗？"
                  @confirm="removeRow(scope.$index)"
              >
                <template #reference>
                  <i class="el-icon-delete delete-btn"></i>
                </template>
              </ElPopconfirm>
            </div>
          </template>
        </el-table-column>
        <el-table-column
            v-for="(head, cindex) in tableData"
            :key="head.formId"
            :min-width="head['min-width']"
            :prop="head.vModel"
        >
          <template #header>
            <span v-if="head.required" style="color: #f56c6c">*</span>
            {{ head.label }}
          </template>
          <template #default="scope" v-if="formOperates[head.vModel]['formOperate'] == 1">
            <DisabledField :field="head" :value="tableFormData[scope.$index][cindex].value"></DisabledField>
          </template>
          <template #default="scope" v-if="formOperates[head.vModel]['formOperate'] == 2">
            <!-- 上传组件 -->
            <el-upload
                v-if="head.tag === 'el-upload'"
                v-bind="getConfById(head.formId)"
                :on-success="res => onUploadSuccess(res, tableFormData[scope.$index][cindex])"
            >
              <template #default>
                已上传 {{ tableFormData[scope.$index][cindex].value.length }}
              </template>
            </el-upload>
            <!-- 其他组件 -->
            <template v-else>
              <component
                  :is="getElement(head)"
                  v-model="tableFormData[scope.$index][cindex].value"
                  v-bind="{...getConfById(head.formId)}"
                  :form-data="formData"
                  @change="updateModelValue"
              />
            </template>
            <div v-show="!tableFormData[scope.$index][cindex].valid" class="error-tip">
              不能为空
            </div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 列表模式 -->
      <template v-if="showList">
        <div v-for="(row, rindex) in tableFormData" :key="rindex" class="list-row">
          <ElTooltip content="删除">
            <i class="el-icon-delete delete-btn" @click="removeRow(rindex)"/>
          </ElTooltip>
          <div
              v-for="(conf, cindex) in config.children"
              :key="cindex"
              class="row-item"
              :class="{ error: !tableFormData[rindex][cindex].valid }"
          >
            <div :style="{ width: labelWidth }">
              <span v-if="conf.required" style="color: #f56c6c">*</span>
              {{ conf.label }}
            </div>
            <div :style="{ 'margin-left': labelWidth }">
              <!--   列表模式，暂不处理，先注释 2025年3月26日22:09:52           -->
              <!--              <render
                                :form-data="formData"
                                :conf="{ ...conf, rowIndex: rindex }"
                                :size="formSize"
                                :model-value="tableFormData[rindex][cindex].value"
                                @update:model-value="val => {
                              tableFormData[rindex][cindex].value = val
                              updateModelValue()
                            }"
                            />-->
            </div>
            <span class="error-tip">不能为空</span>
          </div>
        </div>
        <div v-if="config['show-summary']" class="list-summary">
          <div style="float: left; padding: 6px 12px">合计</div>
          <div style="overflow: hidden; padding-top: 6px">
            <div v-for="(val, name) in listSummation" :key="name">
              {{ val.label }}：{{ val.sum }}
            </div>
          </div>
        </div>
      </template>
      <div class="actions">
        <ElButton type="primary" link @click="addRow">
          <i class="el-icon-plus"/>
          {{ config.actionText }}
        </ElButton>
      </div>
    </div>
  </div>
</template>
<script setup name='FcInputTable'>
import DisabledField from "@/views/flow/createDirectly/generatorForm/FormRender/DisabledField.vue";
import {getElement} from "@/views/flow/formCompoents/getElement.js";
const props = defineProps({
  config: {
    type: Object,
    default: () => ({})
  },
  modelValue: {
    type: [Array,
      Object],
    default: () => []
  },
  formData: Object,
  processDesign: {
    type: Object,
    default: () => undefined
  },
  labelWidth: String,
  formSize: String
})
const emit = defineEmits(['update:modelValue'])
const tableFormData = ref([])
const tableData = ref([])
const listSummation = reactive({})
const isAddRow = ref(true)
// 计算属性
const showTable = computed(() => ['table',
  'default'].includes(props.config.type))
const showList = computed(() => props.config.type === 'list')
// 初始化
onMounted(() => {
  tableData.value = props.config.children
  nextTick(() => {
    initTableData()
  })
})
// 方法
const initTableData = () => {
  if (props.modelValue?.length) {
    props.modelValue.forEach(t => addRow(t))
  } else {
    addRow()
  }
}
const filterProps = () => {
  const conf = props.config.children
  if (!conf) return []
  return conf.map(t => {
    const useable = useableProps.find(p => p.tag === t.tag)
    const res = useable ? useable.props.reduce((r,
                                                key) => (r[key] = t[key], r),
        {}) : t
    return useable?.forceProp ? Object.assign({},
        res,
        useable.forceProp) : res
  })
}
const getConfById = formId => tableData.value.find(t => t.formId === formId)
const getEmptyRow = val => {
  return tableData.value.map(t => ({
    tag: t.tag,
    formId: t.formId,
    value: val?.[t.vModel] ?? t.defaultValue,
    options: t.options,
    valid: true,
    vModel: t.vModel,
    required: t.required
  }))
}
// 行操作
const addRow = (val) => {
  isAddRow.value = true
  tableFormData.value.push(getEmptyRow(val))
  clearAddRowFlag()
}
const removeRow = (index) => {
  tableFormData.value.splice(index,
      1)
}
const clearAddRowFlag = () => {
  setTimeout(() => isAddRow.value = false,
      100)
}
// 数据校验
const checkData = ({
                     tag,
                     value
                   }) => {
  if ([null,
    undefined,
    ''].includes(value)) return false
  if (tag === 'fc-org-select') return checkOrgData(value)
  return Array.isArray(value) ? value.length > 0 : true
}
const checkOrgData = data => {
  if (typeof data !== 'object' || Array.isArray(data)) return false
  return Object.values(data)
      .reduce((sum,
               arr) => sum + (Array.isArray(arr) ? arr.length : 0),
          0) > 0
}
const submit = () => {
  let isValid = true
  tableFormData.value.forEach(row => {
    row.forEach(col => {
      if (col.required && !checkData(col)) {
        col.valid = false
        isValid = false
      }
    })
  })
  return isValid ? tableFormData.value.map(row =>
      row.reduce((acc,
                  cur) => (acc[cur.vModel] = cur.value, acc),
          {})
  ) : false
}
// 文件上传处理
const onUploadSuccess = (response,
                         target) => {
  if (!Array.isArray(target.value)) target.value = []
  target.value.push(response)
}
// 汇总计算
const getListSummaries = () => {
  tableData.value.forEach(row => {
    if (!['fc-amount',
      'el-input-number',
      'el-slider'].includes(row.tag)) return
    const sum = tableFormData.value.reduce((sum,
                                            d) =>
            sum + getCmpValOfRow(d,
                row.vModel),
        0)
    listSummation[row.vModel] = {
      label: row.label,
      sum
    }
  })
}
const getCmpValOfRow = (row,
                        key) => {
  const target = row.find(t => t.vModel === key)
  return target?.value || 0
}
// 表格合计行
const getTableSummaries = ({
                             columns,
                             data
                           }) => {
  const sums = []
  columns.forEach((col,
                   index) => {
    if (index === 0) {
      sums[index] = '合计'
      return
    }
    const sumVal = data.reduce((sum,
                                row) =>
            sum + getCmpValOfRow(row,
                col.property),
        0)
    sums[index] = isNaN(sumVal) ? '' : sumVal
  })
  return sums
}
// 更新模型值
const updateModelValue = () => {
  emit('update:modelValue',
      tableFormData.value.map(row =>
          row.reduce((acc,
                      cur) => (acc[cur.vModel] = cur.value, acc),
              {})
      )
  )
}
const formOperates = computed({
  get() {
    try {
      let obj = {}
      props.processDesign.properties.formOperates.forEach((res) => {
        obj[res.vModel] = res
      })
      return obj
    } catch (e) {
      return undefined
    }
  },
  set() {
  },
})
defineExpose({
  submit
})
</script>
<style scoped lang='scss'>
.FcInputTable {
  width: 100%;
  overflow: hidden;
  .actions {
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
    border: 1px solid #ebeef5;
    border-top: 0;
  }
}
</style>
